package xyz.ibenben.zhongdian.system.service.mongodb.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import xyz.ibenben.zhongdian.system.entity.mongodb.BaseEntityForMongo;
import xyz.ibenben.zhongdian.system.service.mongodb.MongoService;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * @author chenjian
 */
@Slf4j
@Service
@SuppressWarnings("unchecked")
public abstract class AbstractMongoServiceImpl<T extends BaseEntityForMongo> implements MongoService<T> {
    @Resource
    private MongoTemplate mongoTemplate;

    @Override
    public T selectByKey(Object key) {
        Query query = new Query(Criteria.where("id").is(key));
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return mongoTemplate.findOne(query, entityClass);
    }

    @Override
    public void save(T entity) {
        mongoTemplate.save(entity);
    }

    @Override
    public void delete(Object key) {
        Query query = new Query(Criteria.where("id").is(key));
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        mongoTemplate.remove(query, entityClass);
    }

    @Override
    public void updateAll(T entity) {
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Query query = new Query(Criteria.where("id").is(entity.getId()));
        Update update = new Update();
        //得到所有属性
        for (Field field : entityClass.getDeclaredFields()) {
            try {
                //打开私有访问
                field.setAccessible(true);
                update.set(field.getName(), field.get(entity));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        //更新查询返回结果集的第一条
        mongoTemplate.updateFirst(query, update, entityClass);
        //更新查询返回结果集的所有
//        mongoTemplate.updateMulti(query, update, entityClass);
    }

    @Override
    public void updateNotNull(T entity) {
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Query query = new Query(Criteria.where("id").is(entity.getId()));
        Update update = new Update();
        //得到所有属性
        for (Field field : entityClass.getDeclaredFields()) {
            try {
                //打开私有访问
                field.setAccessible(true);
                if (null == field.get(entity)) {
                    continue;
                }
                update.set(field.getName(), field.get(entity));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        //更新查询返回结果集的第一条
        mongoTemplate.updateFirst(query, update, entityClass);
        //更新查询返回结果集的所有
//        mongoTemplate.updateMulti(query, update, entityClass);
    }

    @Override
    public List<T> selectAll() {
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return mongoTemplate.find(new Query(), entityClass);
    }

    @Override
    public void saveBatch(List<T> list) {
        mongoTemplate.insertAll(list);
    }
}
